<template>
    <div class="msg-cover" style="z-index: 10000" v-show="showCover">
        <div class="msg-alert alert-dialog" v-show="showAlert" ref="alert">
            <div class="msg-header" @mousedown="dragElement">
                <span class="msg-title" v-html="alertTitle"></span>
                <button type="button" class="btn-close msg-close" @click.stop="doHideAlert"></button>
            </div>
            <div class="msg-body" :style="{ 'max-height': msgBodyMaxHeight + 'px' }">
                <div v-html="alertMsg"></div>
            </div>
            <div class="msg-footer">
                <div class="footer-button">
                    <button type="button" v-show="showCancel" class="btn btn-secondary cancel" @click.stop="doHideAlert">
                        取消
                    </button>
                    <button type="button" class="btn btn-secondary confirm" @click.stop="doHideAlert">
                        确定
                    </button>
                </div>
            </div>
        </div>
        <div class="msg-loading" v-show="showLoading">
            <div></div>
            <div></div>
            <div></div>
            <span v-show="loadingTip" v-html="loadingTip"></span>
        </div>
    </div>
</template>

<script setup lang="ts">
import "./style.less";
import { onMounted, ref } from "vue";
import EventBus from "../Event";
import {
    CHANGE_LOAD_LOADING_TIP,
    HIDE_LOADING,
    SHOW_CONFIRM,
    SHOW_LOADING,
    SHOW_MSG,
} from "../Event";
import type { ConfirmMessage, AlertMessage } from "../Event";
import { dragElement } from "../Utils";

const alertTitleMsg = "提示";
const loadingTip = ref("");

const alertTitle = ref(alertTitleMsg);
const alertMsg = ref("");
const showCover = ref(false);
const showAlert = ref(false);
const showCancel = ref(false);
let showMessageCount = 0;
let confirmCallback: (confirm: boolean) => void;
const msgBodyMaxHeight = ref(700);
onMounted(() => {
    msgBodyMaxHeight.value = document.documentElement.clientHeight - 300;
});
const doHideAlert = (event: MouseEvent) => {
    if (showMessageCount > 0) {
        showMessageCount--;
    }
    const target = event.target as HTMLElement;
    if (showCancel.value && target instanceof HTMLButtonElement) {
        if (target.className.indexOf("confirm") > -1) {
            confirmCallback(true);
        } else if (target.className.indexOf("cancel") > -1) {
            confirmCallback(false);
        }
    }
    if (showMessageCount === 0) {
        showCover.value = false;
    }
    showAlert.value = false;
    showCancel.value = false;
};

EventBus.on(SHOW_MSG, (config: any) => {
    if (!showAlert.value) {
        showMessageCount++;
    }
    const message = config as AlertMessage;
    if (message.title) {
        alertTitle.value = message.title;
    } else {
        alertTitle.value = alertTitleMsg;
    }
    alertMsg.value = message.msg;
    showCover.value = true;
    showAlert.value = true;
    showCancel.value = false;
});

EventBus.on(SHOW_CONFIRM, (config: any) => {
    showMessageCount++;
    const message = config as ConfirmMessage;
    if (message.title) {
        alertTitle.value = message.title;
    } else {
        alertTitle.value = alertTitleMsg;
    }
    confirmCallback = message.callback;
    alertMsg.value = message.msg;
    showCover.value = true;
    showAlert.value = true;
    showCancel.value = true;
});

let showLoadingCount = 0;
const showLoading = ref(false);
EventBus.on(SHOW_LOADING, (keepLoadingTip: any) => {
    if (!keepLoadingTip) {
        loadingTip.value = "";
    }
    showLoading.value = true;
    showCover.value = true;
    showLoadingCount++;
});
EventBus.on(HIDE_LOADING, () => {
    showLoadingCount--;
    if (showLoadingCount > 0) {
        return;
    }
    showLoading.value = false;
    if (showMessageCount == 0) {
        showCover.value = false;
    }
});
EventBus.on(CHANGE_LOAD_LOADING_TIP, (msg: any) => {
    loadingTip.value = (msg as string) || "";
});
</script>

<style lang="less" scoped>
.alert-dialog {
    transform: translate(-50%, -50%);
}
</style>
